package com.jwsoft.manager.core.dao.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.module.base.common.vo.common.CommonVO;
import com.bifang.module.base.core.integration.CommonIntegration;
import com.jwsoft.manager.common.enums.AreaEnum;
import com.jwsoft.manager.common.vo.eduAddressSchoolAudit.EduAddressSchoolAuditVO;
import com.jwsoft.manager.common.vo.eduAddressTree.AddressTreeVO;
import com.jwsoft.manager.common.vo.eduAddressTree.AddressVO;
import com.jwsoft.manager.common.vo.eduAddressTreeInitial.EduAddressTreeInitialVO;
import com.jwsoft.manager.common.vo.eduAddressTreeSchool.EduAddressTreeSchoolRemoveVO;
import com.jwsoft.manager.common.vo.eduAddressTreeSchool.EduAddressTreeSchoolVO;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.core.dao.mapper.EduAddressMapper;
import com.jwsoft.manager.core.dao.mapper.EduAddressTreeMapper;
import com.jwsoft.manager.core.dao.mapper.EduAddressTreeSchoolMapper;
import com.jwsoft.manager.core.dao.model.EduAddress;
import com.jwsoft.manager.core.dao.model.EduAddressTree;
import com.jwsoft.manager.core.dao.model.EduAddressTreeSchool;
import com.jwsoft.manager.core.dao.service.EduAddressSchoolService;
import com.jwsoft.manager.core.dao.service.EduAddressTreeSchoolService;
import com.jwsoft.manager.core.dao.service.EduAddressTreeService;
import com.jwsoft.manager.core.dao.service.EduSchoolService;
import com.jwsoft.manager.core.util.AddressUtil;
import com.jwsoft.manager.core.util.TextUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 地址树与学校关联表服务实现类
 *
 * @author fangs
 * @since 2023-02-24
 */
@Service
public class EduAddressTreeSchoolServiceImpl extends ServiceImpl<EduAddressTreeSchoolMapper, EduAddressTreeSchool> implements EduAddressTreeSchoolService {
    /**
     * 不保存学校信息的地区级别
     */
    private static final List<String> NOT_SAVE_SCHOOL = Arrays.asList("province", "city");

    /**
     * 地址树最大匹配学层数
     */
    private static final int MAX_MATCH_NUM = 6;

    /**
     * 保存学区信息的最高地区级别，默认为街道、乡镇，可在sys_common中配置
     * 配置的地区级别低于乡镇、街道，高于县时配置不生效，仍保持默认配置
     */
    private static String maxArea = AreaEnum.town.getType();

    @Autowired
    CommonIntegration commonIntegration;

    @Autowired
    EduAddressTreeMapper eduAddressTreeMapper;

    @Autowired
    EduAddressTreeSchoolMapper eduAddressTreeSchoolMapper;

    @Autowired
    EduSchoolService eduSchoolService;

    @Autowired
    EduAddressTreeService addressTreeService;

    @PostConstruct
    public void init() {
        String maxArea2 = commonIntegration.getValueByKey(new CommonVO("save_school_max_area"));
        if (AreaEnum.district.getType().equals(maxArea2)) {
            maxArea = maxArea2;
        }
    }

    /**
     * 保存地址树节点和学校的关联关系
     *
     * @param addressChain 地址链
     * @param eduSchool    学校信息
     * @author fangs
     */
    @Override
    public void saveTreeAndSchool(List<AddressTreeVO> addressChain, EduSchoolVO eduSchool) {
        for (AddressTreeVO addressTreeVO : addressChain) {
            if (NOT_SAVE_SCHOOL.contains(addressTreeVO.getAreaType())) {
                continue;
            }
            if (AreaEnum.district.getType().equals(addressTreeVO.getAreaType())) {
                if (!maxArea.equals(AreaEnum.district.getType())) {
                    continue;
                }
            }
            QueryWrapper<EduAddressTreeSchool> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(EduAddressTreeSchool::getSchoolId, eduSchool.getOrgId())
                    .eq(EduAddressTreeSchool::getTreeId, addressTreeVO.getAddressId());
            if (baseMapper.selectCount(queryWrapper) > 0) {
                continue;
            }
            //保存当前tree和school的关联
            EduAddressTreeSchool treeSchool = new EduAddressTreeSchool();
            treeSchool.setTreeId(addressTreeVO.getAddressId());
            treeSchool.setSchoolId(eduSchool.getOrgId());
            treeSchool.setSchoolCategory(eduSchool.getSchoolCategory());
            treeSchool.setSchoolNature(eduSchool.getSchoolNature());
            treeSchool.setSchoolName(eduSchool.getSchoolName());
            treeSchool.setSchoolNum(eduSchool.getSchoolNum());
            treeSchool.setShortName(eduSchool.getShortName());
            treeSchool.setAreaCode(eduSchool.getAreaCode());
            baseMapper.insert(treeSchool);
        }
    }

    @Override
    public EduAddressTreeSchoolVO saveTreeAndSchool(AddressTreeVO addressTreeVO, EduSchoolVO eduSchool, Integer boundNextNum, Integer boundLeafNum) {
        if (NOT_SAVE_SCHOOL.contains(addressTreeVO.getAreaType())) {
            return null;
        }
        if (AreaEnum.district.getType().equals(addressTreeVO.getAreaType())) {
            if (!maxArea.equals(AreaEnum.district.getType())) {
                return null;
            }
        }
        EduAddressTreeSchool treeSchool = Convert.convert(EduAddressTreeSchool.class, eduSchool);
        treeSchool.setBoundNextNum(boundNextNum);
        treeSchool.setBoundLeafNum(boundLeafNum);
        treeSchool.setSchoolId(eduSchool.getOrgId());
        treeSchool.setTreeId(addressTreeVO.getAddressId());
        save(treeSchool);
        return Convert.convert(EduAddressTreeSchoolVO.class, treeSchool);
    }

    @Override
    public EduAddressTreeSchoolVO saveTreeAndSchool(Long treeId, String schoolId, Integer boundNextNum, Integer boundLeafNum) {
        EduSchoolVO schoolVO = eduSchoolService.getDetail(schoolId);
        if (schoolVO == null) {
            throw new AppException("学校不存在");
        }
        EduAddressTree eduAddressTree = eduAddressTreeMapper.selectById(treeId);
        if (eduAddressTree == null) {
            throw new AppException(String.format("地址树节点不存在,treeId:%s", treeId));
        }
        return saveTreeAndSchool(Convert.convert(AddressTreeVO.class, eduAddressTree), schoolVO, boundNextNum, boundLeafNum);
    }

    /**
     * 根据treeId和ids删除学校关联
     *
     * @param vo
     */
    @Override
    public void removeSchoolRelation(EduAddressTreeSchoolRemoveVO vo) {
        eduAddressTreeSchoolMapper.removeSchoolRelation(vo.getIds(), vo.getTreeId());

    }

    @Override
    public List<EduSchoolVO> matchSchool(String schoolCategory, AddressVO addressVO) {
        List<EduAddressTreeSchool> list = this.match(schoolCategory, addressVO);
        //将地址树节点-学校的关联转换为 学校列表
        List<EduSchoolVO> result = new ArrayList<>(list.size());
        for (EduAddressTreeSchool treeSchool : list) {
            EduSchoolVO school = eduSchoolService.getDetail(treeSchool.getSchoolId());
            result.add(school);
        }
        return result;
    }

    @Override
    public List<EduAddressTreeSchool> matchSchool2(String schoolCategory, AddressVO addressVO) {
        return match(schoolCategory, addressVO);
    }

    /**
     * 根据学校id获取学校能显示的 town列表 树节点id
     * @param orgId  学校id
     * @return
     */
    @Override
    public List<Long> getSchoolInToWnList(String orgId) {
        //得到  学校关联的  区域类型为 town的树节点 信息
        List<EduAddressTree> eduAddressTreeList = baseMapper.querySchoolRelationTownBySchId(orgId);
        if (CollectionUtils.isEmpty(eduAddressTreeList)) {
            return new ArrayList<>();
        }
        return eduAddressTreeList.stream().map(EduAddressTree::getAddressId).collect(Collectors.toList());
    }

    @Override
    public void reviseSchoolNum(AddressTreeVO addressTreeVO, EduSchoolVO schoolVO) {
        //统计下级节点绑定信息
        QueryWrapper<EduAddressTree> treeQueryWrapper = new QueryWrapper<>();
        treeQueryWrapper.lambda().eq(EduAddressTree::getParentId, addressTreeVO.getAddressId())
                .select(EduAddressTree::getAddressId);
        List<EduAddressTree> treeList = eduAddressTreeMapper.selectList(treeQueryWrapper);
        if (CollectionUtils.isEmpty(treeList)) {
            return;
        }
        List<Long> childTreeIds = treeList.stream().map(EduAddressTree::getAddressId).collect(Collectors.toList());
        EduAddressTreeSchool boundSchoolData = baseMapper.queryBoundSchoolNum(childTreeIds, schoolVO.getOrgId());
        int boundLeafNum = 0, boundNextNum = 0;
        if (boundSchoolData.getBoundLeafNum() != null) {
            boundLeafNum = boundSchoolData.getBoundLeafNum();
        }
        boundNextNum = boundSchoolData.getBoundNextNum();
        //查询并更新绑定信息
        QueryWrapper<EduAddressTreeSchool> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduAddressTreeSchool::getTreeId, addressTreeVO.getAddressId())
                .eq(EduAddressTreeSchool::getSchoolId, schoolVO.getOrgId());
        EduAddressTreeSchool treeSchool = getOne(queryWrapper);
        if (treeSchool == null) {
            if (boundLeafNum > 0 || boundNextNum > 0) {
                treeSchool = new EduAddressTreeSchool();
                BeanUtils.copyProperties(schoolVO, treeSchool);
                treeSchool.setSchoolId(schoolVO.getOrgId());
                treeSchool.setTreeId(addressTreeVO.getAddressId());
                treeSchool.setBoundLeafNum(boundLeafNum);
                treeSchool.setBoundNextNum(boundNextNum);
                save(treeSchool);
            }
        } else {
            if (boundLeafNum == 0 && boundNextNum == 0) {
                removeById(treeSchool.getId());
            } else {
                UpdateWrapper<EduAddressTreeSchool> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda().eq(EduAddressTreeSchool::getId, treeSchool.getId())
                        .set(EduAddressTreeSchool::getBoundLeafNum, boundLeafNum)
                        .set(EduAddressTreeSchool::getBoundNextNum, boundNextNum);
                update(updateWrapper);
            }
        }
    }

    @Transactional
    @Override
    public boolean removeByTreeId(Collection<Long> treeIds) {
        if (ObjectUtils.isEmpty(treeIds)) {
            throw new IllegalArgumentException("传入的地址树节点id不能为空");
        }
        LambdaUpdateWrapper<EduAddressTreeSchool> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(EduAddressTreeSchool::getDel, BoolEnum.TRUE.getType())
                .setSql("del_uk=id")
                .in(EduAddressTreeSchool::getTreeId, treeIds);
        return update(updateWrapper);
    }


    /**
     * 根据解析的地址节点，匹配学区
     * @param schoolCategory 需要匹配的学段
     * @param parseNodes     解析的地址节点
     * @return
     */
    @Override
    public List<EduSchoolVO> addressMatchSchool(String schoolCategory, List<EduAddressTreeInitialVO> parseNodes) {
        //下到上寻找节点信息，查找节点匹配关联学校，返回最近匹配的节点
        List<EduSchoolVO> resultList = null;
        for(int i = parseNodes.size() -1 ;i>=0 ; i--){
            EduAddressTreeInitialVO addressNode = parseNodes.get(i);
            //匹配结束的终止节点类型
            ArrayList<String> stopNode = new ArrayList<>();
            stopNode.add(AreaEnum.country.getType());
            stopNode.add(AreaEnum.province.getType());
            stopNode.add(AreaEnum.city.getType());
            stopNode.add(AreaEnum.district.getType());
            if (stopNode.contains(addressNode.getAreaType())){
                break;
            }
            //如果不存在数据库中，就跳过当次循环
            if (BoolEnum.FALSE.getType().equals(addressNode.getExistInDB())){
                continue;
            }
            //根据节点id查询学校关联
            QueryWrapper<EduAddressTreeSchool> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(EduAddressTreeSchool::getTreeId, addressNode.getAddressId())
                    .eq(StringUtils.isNotBlank(schoolCategory),EduAddressTreeSchool::getSchoolCategory, schoolCategory);
            List<EduAddressTreeSchool> list  = list(queryWrapper);
            if (CollectionUtils.isEmpty(list)) {
                if (!AreaEnum.roadNumber.getType().equals(addressNode.getAreaType())){
                    continue;
                }
                //如果是路编号，取路编号父节点下的子节点，比对相似度的路编号信息
                Long parentId = addressNode.getParentId();
                if (parentId == null){
                    continue;
                }
                QueryWrapper<EduAddressTree> treeQueryWrapper = new QueryWrapper<>();
                treeQueryWrapper.lambda()
                        .eq(EduAddressTree::getParentId, parentId)
                        .eq(EduAddressTree::getAreaType,AreaEnum.roadNumber.getType());
                List<EduAddressTree> treeList = eduAddressTreeMapper.selectList(treeQueryWrapper);
                if (treeList.size() <= 1) {
                    continue;
                }

                //路编号 和 学校的关联
                Map<String, List<EduAddressTreeSchool>> roadNumberMap = new HashMap<>();
                //表示有多个路编号信息,找出其他编号是否关联了学校信息
                for (EduAddressTree item : treeList) {
                    QueryWrapper<EduAddressTreeSchool> schoolQueryWrapper = new QueryWrapper<>();
                    schoolQueryWrapper.lambda()
                            .eq(EduAddressTreeSchool::getTreeId, item.getAddressId())
                            .eq(StringUtils.isNotBlank(schoolCategory),EduAddressTreeSchool::getSchoolCategory, schoolCategory);
                    List<EduAddressTreeSchool> roadNumberRelationList = list(schoolQueryWrapper);
                    if (roadNumberRelationList.size() > 0){
                        roadNumberMap.put(item.getAreaName(),roadNumberRelationList);
                    }
                }

                if (roadNumberMap.size() == 0){
                    continue;
                }

                //采用相似度算法比较编号
                String similarityKey = null;
                double maxScore = Double.MIN_VALUE;

                Set<String> keys = roadNumberMap.keySet();
                for (String key : keys) {
                    double similarityScore = TextUtils.calculateSimilarity(addressNode.getAreaName(), key);
                    // 更新最大分数和对应的键
                    if (similarityScore > maxScore) {
                        maxScore = similarityScore;
                        similarityKey = key;
                    }
                }

                list = roadNumberMap.get(similarityKey);
                if (CollectionUtils.isEmpty(list)) {
                    continue;
                }
            }
            //检查是否有停止招生的学校，如果有则移除并从地址树节点-学校关联表中删除
            Iterator<EduAddressTreeSchool> iterator = list.iterator();
            while (iterator.hasNext()) {
                EduAddressTreeSchool treeSchool = iterator.next();
                EduSchoolVO schoolVO = eduSchoolService.getDetail(treeSchool.getSchoolId());
                if (BoolEnum.TRUE.getType().equals(schoolVO.getRecruitStatus())) {
                    //如果学校停止招生，表示为无效数据，从表中移除关联
                    removeById(treeSchool.getId());
                    //从集合中移除关联
                    iterator.remove();
                }
            }
            //判断移除完之后，是否还有数据，没数据就跳过当次循环
            if (!CollectionUtils.isEmpty(list)) {
                //以下是有效的学校数据
                resultList = list.stream().map(item -> {
                    EduSchoolVO schoolVO = eduSchoolService.getDetail(item.getSchoolId());
                    //根据地址节点id和学校id
                    //将是否服务区设置到schoolVO中
                    return schoolVO;
                }).collect(Collectors.toList());
                break;
            }
        }
        if (resultList == null) {
            resultList = new ArrayList<>(0);
        }
        return resultList;
    }

    @Override
    public List<EduSchoolVO> addressMatchSchoolByTreeLink(String schoolCategory, List<EduAddressTree> treeLink) {
        //下到上寻找节点信息，查找节点匹配关联学校，返回最近匹配的节点
        List<EduSchoolVO> resultList = null;
        for (int i = 0; i < treeLink.size(); i++) {
            EduAddressTree eduAddressTree = treeLink.get(i);
            //匹配结束的终止节点类型
            ArrayList<String> stopNode = new ArrayList<>();
            stopNode.add(AreaEnum.country.getType());
            stopNode.add(AreaEnum.province.getType());
            stopNode.add(AreaEnum.city.getType());
            stopNode.add(AreaEnum.district.getType());
            if (stopNode.contains(eduAddressTree.getAreaType())){
                break;
            }
            //根据节点id查询学校关联
            QueryWrapper<EduAddressTreeSchool> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(EduAddressTreeSchool::getTreeId, eduAddressTree.getAddressId())
                    .eq(StringUtils.isNotBlank(schoolCategory),EduAddressTreeSchool::getSchoolCategory, schoolCategory);
            List<EduAddressTreeSchool> list  = list(queryWrapper);
            if (CollectionUtils.isEmpty(list)) {
                if (!AreaEnum.roadNumber.getType().equals(eduAddressTree.getAreaType())){
                    continue;
                }
                //如果是路编号，取路编号父节点下的子节点，比对相似度的路编号信息
                Long parentId = eduAddressTree.getParentId();
                if (parentId == null){
                    continue;
                }
                QueryWrapper<EduAddressTree> treeQueryWrapper = new QueryWrapper<>();
                treeQueryWrapper.lambda()
                        .eq(EduAddressTree::getParentId, parentId)
                        .eq(EduAddressTree::getAreaType,AreaEnum.roadNumber.getType());
                List<EduAddressTree> treeList = eduAddressTreeMapper.selectList(treeQueryWrapper);
                if (treeList.size() <= 1) {
                    continue;
                }

                //路编号 和 学校的关联
                Map<String, List<EduAddressTreeSchool>> roadNumberMap = new HashMap<>();
                //表示有多个路编号信息,找出其他编号是否关联了学校信息
                for (EduAddressTree item : treeList) {
                    QueryWrapper<EduAddressTreeSchool> schoolQueryWrapper = new QueryWrapper<>();
                    schoolQueryWrapper.lambda()
                            .eq(EduAddressTreeSchool::getTreeId, item.getAddressId())
                            .eq(StringUtils.isNotBlank(schoolCategory),EduAddressTreeSchool::getSchoolCategory, schoolCategory);
                    List<EduAddressTreeSchool> roadNumberRelationList = list(schoolQueryWrapper);
                    if (roadNumberRelationList.size() > 0){
                        roadNumberMap.put(item.getAreaName(),roadNumberRelationList);
                    }
                }

                if (roadNumberMap.size() == 0){
                    continue;
                }

                //采用相似度算法比较编号
                String similarityKey = null;
                double maxScore = Double.MIN_VALUE;

                Set<String> keys = roadNumberMap.keySet();
                for (String key : keys) {
                    double similarityScore = TextUtils.calculateSimilarity(eduAddressTree.getAreaName(), key);
                    // 更新最大分数和对应的键
                    if (similarityScore > maxScore) {
                        maxScore = similarityScore;
                        similarityKey = key;
                    }
                }

                list = roadNumberMap.get(similarityKey);
                if (CollectionUtils.isEmpty(list)) {
                    continue;
                }
            }
            //检查是否有停止招生的学校，如果有则移除并从地址树节点-学校关联表中删除
            Iterator<EduAddressTreeSchool> iterator = list.iterator();
            while (iterator.hasNext()) {
                EduAddressTreeSchool treeSchool = iterator.next();
                EduSchoolVO schoolVO = eduSchoolService.getDetail(treeSchool.getSchoolId());
                if (BoolEnum.TRUE.getType().equals(schoolVO.getRecruitStatus())) {
                    //如果学校停止招生，表示为无效数据，从表中移除关联
                    removeById(treeSchool.getId());
                    //从集合中移除关联
                    iterator.remove();
                }
            }
            //判断移除完之后，是否还有数据，没数据就跳过当次循环
            if (!CollectionUtils.isEmpty(list)) {
                //以下是有效的学校数据
                resultList = list.stream().map(item -> {
                    EduSchoolVO schoolVO = eduSchoolService.getDetail(item.getSchoolId());
                    //根据地址节点id和学校id
                    //将是否服务区设置到schoolVO中
                    return schoolVO;
                }).collect(Collectors.toList());
                break;
            }
        }
        if (resultList == null) {
            resultList = new ArrayList<>(0);
        }
        return resultList;
    }

    /**
     * 根据学校id和地址id，移除学校和地址树节点的关联
     * @param schoolId 学校id
     * @param treeNodes 地址树节点链路信息
     */
    @Override
    @Transactional
    public void removeSchoolAndAddressTreeRelation(String schoolId , List<EduAddressTree> treeNodes) {
        if (StringUtils.isBlank(schoolId) || CollectionUtils.isEmpty(treeNodes)){
            return;
        }
        //从小到大遍历
        for (int i = 0; i < treeNodes.size(); i++){
            EduAddressTree treeNode = treeNodes.get(i);
            //删除当前树节点关联的学校
            QueryWrapper<EduAddressTreeSchool> deleteWrapper = new QueryWrapper<>();
            deleteWrapper.lambda().eq(EduAddressTreeSchool::getTreeId,treeNode.getAddressId())
                    .eq(EduAddressTreeSchool::getDelUk,0)
                    .eq(EduAddressTreeSchool::getSchoolId,schoolId);
            EduAddressTreeSchool one = getOne(deleteWrapper);
            if (one != null) {
                //删除学校和地址树节点的关联
                removeById(one.getId());
            }

            //判断父节点，是否能删除 父节点下有其他子节点和学校进行关联就不能进行删除
            if (treeNode.getParentId() != null) {
                QueryWrapper<EduAddressTree> treeQueryWrapper = new QueryWrapper<>();
                treeQueryWrapper.lambda().eq(EduAddressTree::getParentId,treeNode.getParentId());
                //得到当前节点的兄弟节点数据
                List<EduAddressTree> childNode = eduAddressTreeMapper.selectList(treeQueryWrapper);
                List<Long> childNodeIds = childNode.stream().map(EduAddressTree::getAddressId).collect(Collectors.toList());
                //判断兄弟节点是否关联了该学校信息
                QueryWrapper<EduAddressTreeSchool> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(EduAddressTreeSchool::getSchoolId,schoolId)
                        .in(EduAddressTreeSchool::getTreeId,childNodeIds);
                if (count(queryWrapper) > 0) {
                    return;
                }
            }
        }

    }

    /**
     *
     * @param schoolIds
     * @param linkByTreeId
     */
    @Override
    public void removeSchoolsAndAddressTreeRelation(List<String> schoolIds, List<EduAddressTree> linkByTreeId) {
        for (String schoolId : schoolIds) {
            this.removeSchoolAndAddressTreeRelation(schoolId, linkByTreeId);
        }
    }

    @Override
    @Transactional
    public void removeAddressTreeNodeRelationSchool(EduAddressSchoolAuditVO auditVO) {
        if (StringUtils.isBlank(auditVO.getSchoolId())){
            return;
        }
        if (StringUtils.isBlank(auditVO.getAddressId())){
            return;
        }
        if (auditVO.getTreeId() == null){
            return;
        }
        //1.判断子节点和学校是否有关联，有就进行删除
        QueryWrapper<EduAddressTreeSchool> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduAddressTreeSchool::getSchoolId,auditVO.getSchoolId())
                .eq(EduAddressTreeSchool::getTreeId,auditVO.getTreeId());
        if (count(queryWrapper) > 0 ){
            queryWrapper.lambda().select(EduAddressTreeSchool::getId);
            EduAddressTreeSchool addressTreeSchool = getOne(queryWrapper, false);
            removeById(addressTreeSchool.getId());
        }
        //2.判断父节点是否为叶子节点  从下级节点到上级节点
        List<EduAddressTree> treeNodes = addressTreeService.getLinkByTreeId(auditVO.getTreeId());
        if (CollectionUtils.isEmpty(treeNodes)){
            return;
        }
        for (int i = 0; i < treeNodes.size(); i++){
            EduAddressTree node = treeNodes.get(i);
            //如果是子级节点，处理过了，跳过
            if (node.getAddressId().equals(auditVO.getTreeId())){
                continue;
            }
            //判断当前节点是否有学校关联，没有就跳过，
            QueryWrapper<EduAddressTreeSchool> queryExist = new QueryWrapper<>();
            queryExist.lambda().eq(EduAddressTreeSchool::getTreeId,treeNodes.get(i).getAddressId())
                    .eq(EduAddressTreeSchool::getSchoolId,auditVO.getSchoolId());
            if (count(queryExist) == 0){
                continue;
            }
            //得到关联数据
            queryExist.lambda().select(EduAddressTreeSchool::getId);
            EduAddressTreeSchool addressTreeSchool = getOne(queryExist);
            //如果有学校关联，根据该节点得到子级节点的兄弟节点
            List<EduAddressTree> childNode = addressTreeService.getChildrenById(node.getAddressId());

            //判断子节点是否有学校关联
            queryExist.clear();
            queryExist.lambda().eq(EduAddressTreeSchool::getSchoolId,auditVO.getSchoolId())
                    .in(EduAddressTreeSchool::getTreeId,childNode.stream().map(EduAddressTree::getAddressId).collect(Collectors.toList()));
            if (count(queryExist) == 0){
                //如果子节点没有关联学校，删除该节点和学校关联
                QueryWrapper<EduAddressTreeSchool> deleteWrapper = new QueryWrapper<>();
                removeById(addressTreeSchool.getId());
            }else{
                //如果子级节点有关联学校，退出操作
                return;
            }
        }

    }

    private List<EduAddressTreeSchool> match(String schoolCategory, AddressVO addressVO) {
        if (CollectionUtils.isEmpty(addressVO.getAddressChain())) {
            AddressUtil.setAddressChain(addressVO);
        }
        List<AddressTreeVO> addressChain = addressVO.getAddressChain();
        //找到地址树中的最小节点id
        long treeId = -1;
        for (int i = addressChain.size() - 1; i >= 0; i--) {
            AddressTreeVO addressTreeVO = addressChain.get(i);
            if (addressTreeVO.getAddressId() != null) {
                treeId = addressTreeVO.getAddressId();
                break;
            }
        }
        if (treeId == -1) {
            return new ArrayList<>(0);
        }
        List<EduAddressTreeSchool> list = null;
        for (int i = 0; i < MAX_MATCH_NUM && treeId > 0; i++) {
            QueryWrapper<EduAddressTreeSchool> treeSchoolQueryWrapper = new QueryWrapper<>();
            treeSchoolQueryWrapper.lambda().eq(EduAddressTreeSchool::getTreeId, treeId)
                    .eq(EduAddressTreeSchool::getSchoolCategory, schoolCategory);
            list = list(treeSchoolQueryWrapper);
            if (!CollectionUtils.isEmpty(list)) {
                //检查是否有停止招生的学校，如果有则移除并从地址树节点-学校关联表中删除
                Iterator<EduAddressTreeSchool> iterator = list.iterator();
                while (iterator.hasNext()) {
                    EduAddressTreeSchool treeSchool = iterator.next();
                    EduSchoolVO schoolVO = eduSchoolService.getDetail(treeSchool.getSchoolId());
                    if (BoolEnum.TRUE.getType().equals(schoolVO.getRecruitStatus())) {
                        removeById(treeSchool.getId());
                        iterator.remove();
                    }
                }
                //移除停止招生的学校后如果匹配到的学校仍不为空则结束匹配
                if (!CollectionUtils.isEmpty(list)) {
                    break;
                }
            }
            QueryWrapper<EduAddressTree> treeQueryWrapper = new QueryWrapper<>();
            treeQueryWrapper.lambda().eq(EduAddressTree::getAddressId, treeId)
                    .select(EduAddressTree::getAddressId, EduAddressTree::getParentId);
            EduAddressTree eduAddressTree = eduAddressTreeMapper.selectOne(treeQueryWrapper);
            if (eduAddressTree == null) {
                throw new AppException("地址解析信息异常");
            }
            treeId = eduAddressTree.getParentId();
        }
        if (list == null) {
            list = new ArrayList<>(0);
        }
        return list;
    }
}
